package study_thread;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * @author: 李德才
 * @description:
 * @create: 2020-12-12 20:06
 **/

/**
 * CyclicBarrier 满了在做
 */
public class Test_CyclicBarrier {


    /**
     * CyclicBarrier类似于闭锁，与闭锁的关键区别在于，闭锁用于等待事件，
     * 栅栏用于等待其他线程，其作用是让一组线程到达一个屏障时被阻塞，直到最后一个线程到达屏障时，屏障才会开门，所有被屏障拦截的线程才会继续运行。
     * CountDownLatch倾向于一个线程等多个线程，CyclicBarrier倾向于多个线程互相等待
     * CyclicBarrier 默认的构造方法是 CyclicBarrier(int parties)，其参数表示屏障拦截的线程数量，
     * 每个线程调用await方法告诉 CyclicBarrier 我已经到达了屏障，然后当前线程被阻塞。
     */


    /**
     * CyclicBarrier 还提供一个更高级的构造函数CyclicBarrier(int parties, Runnable barrierAction)，
     * 用于在线程到达屏障时，优先执行barrierAction，方便处理更复杂的业务场景。
     */

    /**
     * CyclicBarrier 内部通过一个 count 变量作为计数器，
     * cout 的初始值为 parties 属性的初始化值，每当一个线程到了栅栏这里了，那么就将计数器减一。
     * 如果 count 值为 0 了，表示这是这一代最后一个线程到达栅栏，就尝试执行我们构造方法中输入的任务
     */

    public static void main(String[] args) {
        /**
         * 20 一组,输出五次
         */
        CyclicBarrier barrier = new CyclicBarrier(20, () -> System.out.println("do some thing"));
        for (int i = 0; i < 100; i++) {
            int finalI = i;
            new Thread(() -> {
                try {
                    barrier.await();
//                    System.err.println(barrier.getNumberWaiting());
                    System.err.println(finalI + "===>"+barrier.getParties());
                    System.err.println(finalI + "执行");
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }


}
